package top.meeting.room.module.system.services.impl;

import com.jfinal.kit.HashKit;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.ehcache.CacheKit;
import com.xiaoleilu.hutool.date.DateUtil;
import top.jfinal.jwtTokenPlugin.Bean.IJwtAble;
import top.jfinal.jwtTokenPlugin.kit.JwtKit;
import top.jfinal.jwtTokenPlugin.service.IJwtUserService;
import top.meeting.room.common.constant.ResultEnum;
import top.meeting.room.common.exceptions.HandlerException;
import top.meeting.room.common.kit.ListKit;
import top.meeting.room.module.system.form.LoginForm;
import top.meeting.room.module.system.form.RegisterForm;
import top.meeting.room.module.system.form.SetRoleForm;
import top.meeting.room.module.system.form.UserInfoForm;
import top.meeting.room.module.system.model.Role;
import top.meeting.room.module.system.model.User;
import top.meeting.room.module.system.query.UserQuery;
import top.meeting.room.module.system.services.IUserService;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 我有故事，你有酒么？
 * JKhaled created by yunqisong@foxmail.com 2017/7/22
 * FOR : 用户服务实现
 */
public class UserService implements IUserService, IJwtUserService {

    public static final UserService me = new UserService();

    private UserService() {
    }

    /**
     * 完善用户信息
     *
     * @param userInfoForm
     * @param userId
     * @param roleId
     * @return
     */
    public User updateUserInfo(UserInfoForm userInfoForm, Long userId, Long roleId, Long wxUserId) {
        User user = new User().setDepartment(userInfoForm.getDept())
                .setId(userId)
                .setRealName(userInfoForm.getRealName())
                .setRoleId(roleId)
                .setMobile(userInfoForm.getMobile())
                .setWxUserId(wxUserId);
        user.update();
        remove();
        return (User) login(user.getUserName(), user.getOpenId());
    }

    public IJwtAble login(String userName, String password) {
        User retVal = null;
        if (StrKit.notBlank(password, userName)) {
            retVal = CacheKit.get(User.user_login, String.valueOf(password + userName));
            if (retVal == null) {
                SqlPara sql = Db.use().getSqlPara(User.user_login, new Kv().set(User.userName, userName));
                retVal = User.dao.findFirst(sql);
                if (retVal != null && retVal.getPassword().equals(HashKit.md5(password.trim()))) {
                    CacheKit.put(User.user_login, String.valueOf(password + userName), retVal);
                }
            }
        }
        return retVal;
    }

    public User modifyPassword(String newPassword, Long id) {
        User user = getModel(id);
        if (user == null)
            throw new HandlerException(ResultEnum.DATA_ERROR, "找不到用户");
        if (StrKit.isBlank(newPassword))
            throw new HandlerException(ResultEnum.DATA_ERROR, "新设置的密码不可以为空");
        user.setPassword(getSavePassword(newPassword));
        user.update();
        remove();
        return user;
    }

    private String getSavePassword(String password) {
        return HashKit.md5(password);
    }

    public Boolean resetPassword(String ids) {
        if (StrKit.isBlank(ids))
            throw new HandlerException(ResultEnum.DATA_ERROR, "要重置的ID不可以全为空");
        SqlPara sqlPara = User.dao.getSqlPara(User.user_resetPassword, Kv.by("password", getSavePassword("123456")).set("ids", ListKit.ids2List(ids)));
        Db.update(sqlPara.getSql());
        remove();
        return true;
    }


    /**
     * 不可以手动保存，必须注册用户
     */
    public User saveAsModel(LoginForm LoginForm) {
        return null;
    }

    /**
     * 不可以手动保存，必须注册用户
     */
    public Record saveAsRecord(LoginForm LoginForm) {
        return null;
    }

    public User register(RegisterForm registerForm) {
        User user = null;
        if (isAllowed(registerForm)) {
            Date now = DateUtil.date();
            user = new User();
            user.setUserName(StrKit.notBlank(registerForm.getUserName()) ? registerForm.getUserName() : null);
            user.setPassword(getSavePassword(registerForm.getPassword()));
            user.setCreated(now);
            user.setUpdated(now);
            user.setLastModifyPasswordTime(now);
            user.setDeleted(User.makeRecover);
            user.setOpenId(registerForm.getOpenId());
            user.setWxUserId(registerForm.getWxUserId());
            user.save();
        }
        remove();
        return user;
    }

    private Boolean isAllowed(RegisterForm registerForm) {
        if (registerForm == null)
            throw new HandlerException(ResultEnum.DATA_ERROR, "保存的表单不可以为空");
        if (StrKit.isBlank(registerForm.getMobile())
//                && StrKit.isBlank(registerForm.getEmail())
                && StrKit.isBlank(registerForm.getUserName()))
            throw new HandlerException(ResultEnum.DATA_ERROR, "手机号,不可以全为空");
        if (StrKit.isBlank(registerForm.getPassword()))
            throw new HandlerException(ResultEnum.DATA_ERROR, "密码不可以为空");
        return true;
    }

    public Boolean isExist(String text) {
        if (StrKit.isBlank(text))
            throw new HandlerException(ResultEnum.DATA_ERROR, "用户名或者手机号或者邮箱不可以全为空");
        User user = CacheKit.get(User.user_isExist, text);
        if (user == null) {
            SqlPara sqlPara = User.dao.getSqlPara(User.user_isExist, Kv.by("text", text));
            user = User.dao.findFirst(sqlPara.getSql());
            if (user == null) return false;
        }
        return true;
    }

    public Page<User> pageModel(UserQuery userQuery) {
        if (userQuery == null)
            throw new HandlerException(ResultEnum.DATA_ERROR, "查询参数不可以空");
        Page<User> retVal = CacheKit.get(User.user_pageModel, String.valueOf(userQuery));
        if (retVal == null) {
            SqlPara sqlPara = User.dao.getSqlPara(User.user_pageModel,
                    Kv.by("params", userQuery.getParams()).set("deleted", userQuery.getDeleted() == null ? 0 : userQuery.getDeleted()));
            sqlPara.setSql(sqlPara.getSql().replaceFirst(" AND ", " WHERE "));
            retVal = User.dao.paginate(userQuery.getPage() == null ? 1 : userQuery.getPage(),
                    userQuery.getSize() == null ? 10 : userQuery.getSize(), sqlPara);
            CacheKit.put(User.user_pageModel, String.valueOf(userQuery), retVal);
        }
        return retVal;
    }

    public Page<Record> pageRecord(UserQuery userQuery) {
        if (userQuery == null)
            throw new HandlerException(ResultEnum.DATA_ERROR, "查询参数不可以空");
        Page<Record> retVal = CacheKit.get(User.user_pageRecord, String.valueOf(userQuery));
        if (retVal == null) {
            Page<User> userPage = pageModel(userQuery);
            retVal = new Page<Record>(userPage.getList().stream().map(user -> {
                return user.toUserWithRole();
            }).collect(Collectors.toList()), userPage.getPageNumber(), userPage.getPageSize(), userPage.getTotalPage(), userPage.getTotalRow());
            CacheKit.put(User.user_pageRecord, String.valueOf(userQuery), retVal);
        }
        return retVal;
    }

    public User getModel(Long id) {
        if (id == null)
            throw new HandlerException(ResultEnum.DATA_ERROR, "获取的个体ID不可以为空");
        User retVal = CacheKit.get(User.user_getModel, String.valueOf(id));
        if (retVal == null) {
            retVal = User.dao.findById(id);
            CacheKit.put(User.user_getModel, String.valueOf(id), retVal);
        }
        return retVal;
    }

    public Record getRecord(Long id) {
        if (id == null)
            throw new HandlerException(ResultEnum.DATA_ERROR, "获取的个体ID不可以为空");
        Record retVal = CacheKit.get(User.user_getRecord, String.valueOf(id));
        if (retVal == null) {
            User user = getModel(id);
            retVal = user == null ? null : user.toUserWithRole();
            CacheKit.put(User.user_getRecord, String.valueOf(id), retVal);
        }
        return retVal;
    }

    public void deleteById(Long id) {
        deleteByIds(String.valueOf(id));
    }

    public void deleteByIds(String ids) {
        toStateByIds(ids, 1);
    }

    public void recoveryByIds(String ids) {
        toStateByIds(ids, 0);
    }

    public void setRole(SetRoleForm roleForm) {
        if (roleForm == null || roleForm.getRoleId() == null || roleForm.getUserId() == null)
            throw new HandlerException(ResultEnum.DATA_ERROR, "表单数据为空");
        SqlPara sqlPara = Db.getSqlPara(User.user_setRole, Kv.by("roleId", roleForm.getRoleId()).set("userId", roleForm.getUserId()));
        Db.update(sqlPara.getSql(), sqlPara.getPara());
        remove();
    }

    public List<User> findByRoleName(String roleName) {
        List<User> retVal = CacheKit.get(User.user_findByRoles, String.valueOf(roleName));
        if (retVal == null) {
            Role role = RoleService.me.findByRoleName(roleName);
            if (role != null) {
                SqlPara sql = User.dao.getSqlPara(User.user_findByRoles, Kv.by("roleId", role.getId()));
                retVal = User.dao.find(sql);
            }
            CacheKit.put(User.user_findByRoles, String.valueOf(roleName), retVal);
        }
        return retVal;
    }

    @Override
    public List<User> findSp() {
        List<User> retVal = CacheKit.get(User.user_findByRoles, User.user_findByRoles);
        if (retVal == null) {
            retVal = User.dao.find(User.dao.getSql(User.user_findSp));
            CacheKit.put(User.user_findByRoles, User.user_findByRoles, retVal);
        }
        return retVal;
    }

    public void setSp(Long id) {
        User user = User.dao.findById(id);
        user.setSpForce(!user.getSpForce());
        user.update();

        remove();
    }

    public void toStateByIds(String ids, Integer state) {
        List<Long> idList = ListKit.ids2List(ids);
        if (idList == null || idList.size() == 0)
            throw new HandlerException(ResultEnum.DATA_ERROR, "至少操作一条数据");
        List<User> users = User.dao.find(User.dao.getSqlPara(User.user_findByIds, Kv.by("ids", idList)));
        for (User user : users) {
            Record role = user.getRole();
            if (role != null && role.getLong(Role.id) == 1L)
                throw new HandlerException(ResultEnum.DATA_ERROR, "不可以操作超级管理员");
        }
        SqlPara sqlPara = User.dao.getSqlPara(User.user_toStateByIds, Kv.by("state", state).set("ids", idList));
        Db.update(sqlPara.getSql(), sqlPara.getPara());
        remove();
    }

    public void remove() {
        CacheKit.removeAll(User.user_login);
        CacheKit.removeAll(User.user_getRole);
        CacheKit.removeAll(User.user_getRoles);
        CacheKit.removeAll(User.user_getModel);
        CacheKit.removeAll(User.user_pageModel);
        CacheKit.removeAll(User.user_getForces);
        CacheKit.removeAll(User.user_pageRecord);
        CacheKit.removeAll(User.user_getPicture);
        CacheKit.removeAll(User.user_findByRoles);

        // 更新用户信息
        JwtKit.storeReset();
    }
}
